package com.jsu.clubmanagementsystem.service.activity.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jsu.clubmanagementsystem.common.ErrorCode;
import com.jsu.clubmanagementsystem.exception.BusinessException;
import com.jsu.clubmanagementsystem.model.entity.Activity;
import com.jsu.clubmanagementsystem.model.entity.ActivityApplication;
import com.jsu.clubmanagementsystem.model.entity.UserApplication;
import com.jsu.clubmanagementsystem.model.enums.ActivityStatusEnum;
import com.jsu.clubmanagementsystem.model.enums.ApplicationTypeEnum;
import com.jsu.clubmanagementsystem.model.enums.ReviewResultEnum;
import com.jsu.clubmanagementsystem.service.activity.ActivityService;
import com.jsu.clubmanagementsystem.service.application.ActivityApplicationService;
import com.jsu.clubmanagementsystem.service.application.UserApplicationService;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledFuture;


@Service
@Slf4j
public class ActivityScheduler {

    @Resource
    private ActivityService activityService;

    @Resource
    private TaskScheduler taskScheduler;

    @Resource
    private ActivityApplicationService activityApplicationService;

    @Resource
    private UserApplicationService userApplicationService;

    /**
     * 管理任务的集合
     */
    private Map<Long, List<ScheduledFuture<?>>> activityTasks = new ConcurrentHashMap<>();

    /**
     * 项目初始化时遍历活动表
     */
    @PostConstruct
    public void init() {
        QueryWrapper<Activity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", ActivityStatusEnum.READY.getCode());
        List<Activity> activities = activityService.list(queryWrapper);
        for (Activity activity : activities) {
            createTask(activity);
        }
    }

    public void createTask(Activity activity) {
        Date nowTime = new Date();
        Date startTime = activity.getStartTime();
        Date endTime = activity.getEndTime();

        if (nowTime.before(startTime)) {
            scheduleTask(activity, startTime, ActivityStatusEnum.START);
            scheduleTask(activity, endTime, ActivityStatusEnum.END);
        } else if (nowTime.after(endTime)) {
            updateActivityStatus(activity, ActivityStatusEnum.END);
        } else {
            updateActivityStatus(activity, ActivityStatusEnum.START);
            scheduleTask(activity, endTime, ActivityStatusEnum.END);
        }
    }

    public void processUpdateActivity(Activity activity){
        ActivityStatusEnum status = ActivityStatusEnum.getStatusEnumByCode(activity.getStatus());
        switch (status) {
            case READY:
                if (activity.getCreateTime().equals(activity.getUpdateTime())) {
                    log.info("创建新活动任务: {}", activity.getId());
                    createTask(activity);
                } else {
                    log.info("更新活动任务: {}", activity.getId());
                    updateExistingTasks(activity);
                }
                break;
            case CANCEL:
                log.info("取消活动任务: {}", activity.getId());
                cancelTasks(activity.getId());
                break;
            default:
                log.warn("未处理的活动状态: {}, 活动ID: {}", status, activity.getId());
        }
    }

    private void scheduleTask(Activity activity, Date executeTime, ActivityStatusEnum newStatus) {
        ScheduledFuture<?> future = taskScheduler.schedule(
                () -> updateActivityStatus(activity, newStatus),
                executeTime
        );
        if (activityTasks.containsKey(activity.getId())){
            activityTasks.get(activity.getId()).add(future);
        } else {
            List<ScheduledFuture<?>> tasks = new ArrayList<>();
            tasks.add(future);
            activityTasks.put(activity.getId(), tasks);
        }
    }

    /**
     * 更新活动状态
     *
     * @param activity
     * @return
     */
    @Transactional
    public void updateActivityStatus(Activity activity, ActivityStatusEnum targetStatus) {
        activity.setStatus(targetStatus.getCode());
        if (!activityService.updateById(activity)) {
            log.error("活动编号为:  {} 的活动修改状态为 {} 失败", activity.getId(), targetStatus);
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "修改活动状态失败");
        }

        QueryWrapper<ActivityApplication> activityApplicationQueryWrapper = new QueryWrapper<>();
        activityApplicationQueryWrapper.eq("targetId", activity.getId());
        activityApplicationQueryWrapper.in("type",
                ApplicationTypeEnum.DELETE_ACTIVITY.getCode(), ApplicationTypeEnum.CHANGE_ACTIVITY_INFO.getCode());
        activityApplicationQueryWrapper.eq("result", ReviewResultEnum.WAITING.getCode());
        if (activityApplicationService.count(activityApplicationQueryWrapper) > 0 &&
            activityApplicationService.remove(activityApplicationQueryWrapper)){
            log.error("活动编号为:  {} 的活动，删除未被审核的删除活动申请和修改活动信息申请 失败", activity.getId());
        }

        QueryWrapper<UserApplication> userApplicationQueryWrapper = new QueryWrapper<>();
        userApplicationQueryWrapper.eq("additionalInfo", activity.getId());
        userApplicationQueryWrapper.in("type",
                ApplicationTypeEnum.ENGAGE_ACTIVITY.getCode(), ApplicationTypeEnum.QUIT_ACTIVITY.getCode());
        userApplicationQueryWrapper.eq("result", ReviewResultEnum.WAITING.getCode());
        if (userApplicationService.count(userApplicationQueryWrapper) > 0 &&
                userApplicationService.remove(userApplicationQueryWrapper)){
            log.error("活动编号为:  {} 的活动，删除还未审核的参加活动申请和退出活动申请 失败", activity.getId());
        }

        removeCompletedTask(activity.getId());
    }

    public List<ScheduledFuture<?>> getTasksByActivityId(Long activityId) {
        if (activityTasks.containsKey(activityId)){
            return activityTasks.get(activityId);
        } else {
            return null;
        }
    }

    private void removeCompletedTask(Long activityId) {
        List<ScheduledFuture<?>> tasks = activityTasks.get(activityId);
        if (tasks != null) {
            tasks.removeIf(ScheduledFuture::isDone);
            if (tasks.isEmpty()) {
                activityTasks.remove(activityId);
            }
        }
    }

    private void updateExistingTasks(Activity activity) {
        List<ScheduledFuture<?>> tasks = activityTasks.get(activity.getId());
        if (tasks != null) {
            tasks.forEach(task -> task.cancel(false));
            activityTasks.remove(activity.getId());
        }
        createTask(activity);
    }

    private void cancelTasks(Long activityId) {
        List<ScheduledFuture<?>> tasks = activityTasks.remove(activityId);
        if (tasks != null) {
            tasks.forEach(task -> task.cancel(false));
            log.info("已取消活动 {} 的所有任务", activityId);
        }
    }
}
